/**
 * 在线用户管理模块---管理进入游戏大厅的和进入游戏房间的(此时才会建立长连接)
 * 将用户ID与客户端websocket长连接关联起来
 * 客户端可以通过ID找到用户的连接，进行推送消息
 * 可以通过判断一个用户是否还在用户管理模块中，来确定是否在线
 */

#pragma once
#include"Detail.hpp"
#include<unordered_map>
#include<mutex> 


namespace OnlineGoBang
{
    class OnlineManager
    {
    public:
        //websocket连接建立时，会有加入游戏大厅/房间的用户
        //用户进入游戏大厅
        void EnterGameHall(const uint64_t& uid,const wsserver_t::connection_ptr& con)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _hall_users.insert({uid,con});
        }
        //用户进入游戏房间
        void EnterGameRoom(const uint64_t& uid,const wsserver_t::connection_ptr& con)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _room_users.insert({uid,con});
        }

        //websocket连接断开时，会有用户退出游戏大厅/房间
        //用户退出大厅
        void ExitGameHall(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _hall_users.erase(uid);
        }
        //用户退出房间
        void ExitGameRoom(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            _room_users.erase(uid);
        }

        //判断指定用户是否在大厅
        bool InHall(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it=_hall_users.find(uid);
            if(it==_hall_users.end())
            {
                return false;
            }
            return true;
        }
        //判断指定用户是否在房间
        bool InRoom(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it=_room_users.find(uid);
            if(it==_room_users.end())
            {
                return false;
            }
            return true;
        }

        //通过用户ID在大厅中获取用户连接
        wsserver_t::connection_ptr GetConnectionFromHall(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it=_hall_users.find(uid);
            if(it==_hall_users.end())
            {
                return wsserver_t::connection_ptr();
            }
            return it->second;
        }
        //通过用户ID在房间中获取用户连接
        wsserver_t::connection_ptr GetConnectionFromRoom(const uint64_t& uid)
        {
            std::unique_lock<std::mutex> lock(_mutex);
            auto it=_room_users.find(uid);
            if(it==_room_users.end())
            {
                return wsserver_t::connection_ptr();
            }
            return it->second;
        }
        
    private:
        std::unordered_map<uint64_t,wsserver_t::connection_ptr> _hall_users;//游戏大厅用户
        std::unordered_map<uint64_t,wsserver_t::connection_ptr> _room_users;//游戏房间用户
        std::mutex _mutex;
    };
}